﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
// 原题连接：https://www.acwing.com/problem/content/description/175/
/*
题目描述：
给定一个 N
 行 M
 列的 01
 矩阵 A
，A[i][j]
 与 A[k][l]
 之间的曼哈顿距离定义为：

dist(A[i][j],A[k][l])=|i−k|+|j−l|
输出一个 N
 行 M
 列的整数矩阵 B
，其中：

B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y])
输入格式
第一行两个整数 N,M
。

接下来一个 N
 行 M
 列的 01
 矩阵，数字之间没有空格。

输出格式
一个 N
 行 M
 列的矩阵 B
，相邻两个整数之间用一个空格隔开。

数据范围
1≤N,M≤1000
输入样例：
3 4
0001
0011
0110
输出样例：
3 2 1 0
2 1 0 0
1 0 0 1
*/

// 开始解题：
// 方法——bfs
int n = 0, m = 0;
int dx[4] = { -1, 1, 0, 0 }, dy[4] = { 0, 0, -1, 1 };
char grid[1010][1010];
int ret[1010][1010];
bool vis[1010][1010];
int main() {
	memset(vis, false, sizeof vis);
	scanf("%d%d", &n, &m);
	queue<pair<int, int>> q;
	for (int i = 0; i < n; i++) {
		scanf("%s", grid[i]);
	}


	// 将所有的起点放入队列
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (grid[i][j] == '1') {
				vis[i][j] = true;
				q.push({ i, j });
			}
		}
	}

	int step = 0;
	while (!q.empty()) {
		int size = q.size();
		step++;
		while (size--) {
			int a = q.front().first, b = q.front().second;
			q.pop();
			for (int k = 0; k < 4; k++) {
				int x = a + dx[k], y = b + dy[k];
				if (x >= 0 && x < n && y >= 0 && y < m && !vis[x][y] && grid[x][y] == '0') {
					vis[x][y] = true;
					ret[x][y] = step;
					q.push({ x, y });
				}
			}
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			printf("%d ", ret[i][j]);
		}
		printf("\n");
	}
	return 0;
}

